/********************************************************************************
 * Copyright (c) 2019 [Open Lowcode SAS](https://openlowcode.com/)
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0 .
 *
 * SPDX-License-Identifier: EPL-2.0
 ********************************************************************************/

package org.openlowcode.server.data.properties;

import java.util.ArrayList;

import org.openlowcode.module.system.data.choice.ApplocaleChoiceDefinition;
import org.openlowcode.server.data.ChoiceValue;
import org.openlowcode.server.data.DataObject;
import org.openlowcode.server.data.DataObjectDefinition;
import org.openlowcode.server.data.DataObjectElement;
import org.openlowcode.server.data.DataObjectPayload;
import org.openlowcode.server.data.DataObjectPropertyDefinition;
import org.openlowcode.server.data.PropertyExtractor;
import org.openlowcode.server.data.loader.FlatFileLoaderColumn;
import org.openlowcode.server.data.specificstorage.ExternalFieldSchema;
import org.openlowcode.server.data.storage.QueryCondition;
import org.openlowcode.server.data.storage.StoredTableIndex;
import org.openlowcode.server.data.storage.StringStoredField;

/**
 * @author <a href="https://openlowcode.com/" rel="nofollow">Open Lowcode
 *         SAS</a>
 *
 * @param <E>
 */
public class VersionedDefinition<E extends DataObject<E>>
		extends
		DataObjectPropertyDefinition<E> {
	private StringStoredField version;
	private StringStoredField lastversion;
	private StringStoredField masterid;
	@SuppressWarnings("unused")
	private UniqueidentifiedDefinition<E> uniqueidentifieddefinition;

	public VersionedDefinition(DataObjectDefinition<E> parentobject) {
		super(parentobject, "VERSIONED");
		this.version = new StringStoredField("VERSION", null, 8, "A");
		this.addFieldSchema(this.version);
		this.lastversion = new StringStoredField("LASTVERSION", null, 1, "Y");
		this.addFieldSchema(this.lastversion);
		this.masterid = new StringStoredField("MASTERID", null, 200);
		this.addFieldSchema(this.masterid);
		StoredTableIndex msidindex = new StoredTableIndex("MSID");
		msidindex.addStoredFieldSchema(masterid);
		this.addIndex(msidindex);
	}

	@Override
	public ArrayList<ExternalFieldSchema<?>> generateExternalSchema() {
		ArrayList<ExternalFieldSchema<?>> externalfieldlist = new ArrayList<ExternalFieldSchema<?>>();
		return externalfieldlist;
	}

	@Override
	public QueryCondition getUniversalQueryCondition(String alias) {
		// by default, do not filter for old version and feedbacks all the versions
		return null;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public org.openlowcode.server.data.DataObjectPropertyDefinition.FieldSchemaForDisplay[] setFieldSchemaToDisplay() {
		FieldSchemaForDisplay<E>[] returnvalue = new FieldSchemaForDisplay[3];
		returnvalue[0] = new FieldSchemaForDisplay("Object Master Id",
				"the technical id generated by the system to identify all versions of the same object", masterid, false,
				true, -71, 20, this.parentobject);
		returnvalue[1] = new FieldSchemaForDisplay("Latest Version", "", lastversion, false, false, -5, 5,
				this.parentobject);
		returnvalue[2] = new FieldSchemaForDisplay<E>("Version", "Identifier of the version", version, true, false,
				true, 890, 20, this.parentobject);

		return returnvalue;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public FlatFileLoaderColumn<E> getFlatFileLoaderColumn(
			DataObjectDefinition<E> objectdefinition,
			String[] columnattributes,
			PropertyExtractor<E> propertyextractor,
			ChoiceValue<ApplocaleChoiceDefinition> locale) {
		if (columnattributes == null)
			throw new RuntimeException("At least one attribute required for Versioned: MASTERID");
		if (columnattributes != null)
			if (columnattributes.length == 0)
				throw new RuntimeException("At least one attribute required for Versioned: MASTERID");
		if ("MASTERID".equals(columnattributes[0])) {
			return new VersionedMasterIdFlatFileLoader(objectdefinition, this, false, propertyextractor);
		}
		return null;
	}

	@Override
	public String[] getLoaderFieldList() {
		return new String[] { "MASTERID" };
	}

	@Override
	public String[] getLoaderFieldSample(String name) {
		if (name.equals("MASTERID")) {
			String[] returntable = new String[4];
			returntable[0] = this.getName() + "&MASTERID";
			returntable[1] = "OPTIONAL";
			returntable[2] = "a8c7d";
			returntable[3] = "the master id of the object (for export only)";
			return returntable;
		}
		return null;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public DataObjectElement initiateFieldInstance(DataObjectPayload parentpayload) {
		return new Versioned(this, parentpayload);
	}

	/**
	 * sets the dependent property unique identified
	 * 
	 * @param uniqueidentifieddefinition definition of property unique identified
	 */
	public void setDependentDefinitionUniqueidentified(UniqueidentifiedDefinition<E> uniqueidentifieddefinition) {
		this.uniqueidentifieddefinition = uniqueidentifieddefinition;
	}

	/**
	 * gets the dependent property unique identified definition
	 * 
	 * @return unique identified property definition for the same object
	 */
	public UniqueidentifiedDefinition<E> getDependentDefinitionUniqueidentified() {
		return this.uniqueidentifieddefinition;
	}
}
